home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- %
- % The MU-puzzle
- % from Hofstadter's "Godel, Escher, Bach" (pp. 33-6).
- %
-
- % To find a derivation type, for example:
- % theorem(muiiu).
- % Also try 'miiiii' (uses all rules) and 'muui' (requires 11 steps).
- % Note that it can be shown that (# of i's) cannot be a multiple
- % of three (which includes 0).
-
- % Some results:
- %
- % string # steps
- % ------ -------
- % mi 1
- % mu -
- % mii 2
- % miu 2
- % mui 4
- % muu -
- % miii -
- % miiu 3
- % miui 8
- % miuu 5
- % muii 8
- % muiu 5
- % muui 11
- % muuu -
- % miiii 3
- % miiiu -
- % miiui -
- % miiuu 6
- % miuii -
- % miuiu 3
- % miuui 6
- % miuuu 9
- % muiii -
- % muiiu 6
- % muiui 5
- % muiuu 9
- % muuii 6
- % muuiu 9
- % muuui 9
- % muuuu -
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- main :- theorem(muui).
-
- % First break goal atom into a list of characters,
- % find the derivation, and then print the results.
- theorem(Goal) :-
- explode(Goal, G),
- length(G, GL1),
- GL is GL1 - 1,
- derive([m,i], G, 1, GL, Derivation, 0),
- nl, print_results([rule(0,[m,i])|Derivation], 0).
-
- % derive(StartString, GoalString, StartStringLength, GoalStringLength,
- % Derivation, InitBound).
- derive(S, G, SL, GL, D, B) :-
- B1 is B + 1,
- write('depth '), write(B1), nl,
- derive2(S, G, SL, GL, 1, D, B).
- derive(S, G, SL, GL, D, B) :-
- B1 is B + 1,
- derive(S, G, SL, GL, D, B1).
-
- % derive2(StartString, GoalString, StartStringLength, GoalStringLength,
- % ScanPointer, Derivation, NumRemainingSteps).
- derive2(S, S, SL, SL, _, [], _).
- derive2(S, G, SL, GL, Pin, [rule(N,I)|D], R) :-
- lower_bound(SL, GL, B),
- R >= B,
- R1 is R - 1,
- rule(S, I, SL, IL, Pin, Pout, N),
- derive2(I, G, IL, GL, Pout, D, R1).
-
- rule([m|T1], [m|T2], L1, L2, Pin, Pout, N) :-
- rule(T1, T2, L1, L2, Pin, Pout, 1, i, N, X-X).
-
- % rule(InitialString, FinalString, InitStrLength, FinStrLength,
- % ScanPtrIn, ScanPtrOut, StrPosition, PreviousChar,
- % RuleNumber, DifferenceList).
- % The difference list is used for doing a list concatenate in rule 2.
- rule([i], [i,u], L1, L2, Pin, Pout, Pos, _, 1, _) :-
- Pos >= Pin,
- Pout is Pos - 2,
- L2 is L1 + 1.
- rule([], L, L1, L2, _, 1, _, _, 2, L-[]) :-
- L2 is L1 + L1.
- rule([i,i,i|T], [u|T], L1, L2, Pin, Pout, Pos, _, 3, _) :-
- Pos >= Pin,
- Pout is Pos - 1,
- L2 is L1 - 2.
- rule([u,u|T], T, L1, L2, Pin, Pout, Pos, i, 4, _) :-
- Pos >= Pin,
- Pout is Pos - 2,
- L2 is L1 - 2.
- rule([H|T1], [H|T2], L1, L2, Pin, Pout, Pos, _, N, L-[H|X]) :-
- Pos1 is Pos + 1,
- rule(T1, T2, L1, L2, Pin, Pout, Pos1, H, N, L-X).
-
- print_results([], _).
- print_results([rule(N,G)|T], M) :-
- M1 is M + 1,
- implode(A, G),
- write(M1), write(' '), print_rule(N), write(A), nl,
- print_results(T, M1).
-
- print_rule(0) :- write('axiom ').
- print_rule(N) :- N =\= 0, write('rule '), write(N), write(' ').
-
- % Break atom A into list of characters L.
- explode(A, L) :-
- name(A, Ascii),
- name_list(L, Ascii).
-
- % Combine list of characters L into atom A.
- implode(A, L) :-
- name_list(L, Ascii),
- name(A, Ascii).
-
- name_list([], []).
- name_list([H1|T1], [H2|T2]) :-
- name(H1, [H2]),
- name_list(T1, T2).
-
- lower_bound(N, M, 1) :- N < M.
- lower_bound(N, N, 2).
- lower_bound(N, M, B) :-
- N > M,
- Diff is N - M,
- (even(Diff) ->
- B is Diff // 2;
- B is (Diff + 1) // 2 + 1).
-
- even(N) :- 0 is (N mod 2).
-